# 函数
# 定义
# 计算1~n的和
# 函数参数：n
# （省略）函数的返回值类型：int
# 实现特定功能的代码块
def sumN(n):
    sum = 0
    i = 1
    while i <= n:
        sum += i
        i += 1
    print(sum)


sumN(10)


# 计算n的阶乘
# 5!=5*4*3*2*1
# 两种方式
# 用循环
def jieCheng(n):
    res = 1
    while n >= 1:
        res *= n
        n -= 1
    print(res)


jieCheng(5)


# 用递归
# 递归函数：
# 1、结束条件
# 2、自己调用自己
def jieCheng2(n):
    if n == 1:
        return 1
    return n * jieCheng2(n - 1)


print(jieCheng2(5))
# 能使用循环就使用循环 尽量避免使用递归

# 匿名函数
# lambda表达式
# 替代一些简单的函数

f = lambda x, y: x > y
print(f(10, 2))
print(f(2, 10))


# import this

# 函数的参数

# 位置参数(必选参数)
# 计算x的平方
def func1(x):
    return x ** 2


print(func1(2))


# 计算x的n次方

def func2(x, n):
    return x ** n


print(func2(2, 3))


# 计算x的n次方，如果不传入n则默认计算x的平方
# 参数n ：默认参数，在调用函数的时候可以不传入，使用默认值
def func3(x, n=2):
    return x ** n


print(func3(2, 4))
print(func3(2))

# 计算1,2,3,4,5,6的和
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


def func4(l):
    sum = 0
    for i in l:
        sum += i
    return sum


print(func4(list1))


# 可变参数 *args
def func5(*args):
    sum = 0
    for i in args:
        sum += i
    return sum


print(func5(1))
print(func5(1, 2))
print(func5(1, 2, 3))
print(func5(1, 2, 3, 4))

# print(func5(list1[0], list1[1], list1[2]))
# *list1 将list1全部展开，每个元素作为一个参数
print(func5(*list1))


# 关键字参数
# 同可变参数最大的区别就是：传入参数的时候需不需要指定参数名

# **kw 关键字参数
def register(id, name, phone, **kw):
    dict1 = {
        'id': id,
        'name': name,
        'phone': phone,
        'other': kw
    }
    print(dict1)


register('001', 'zhangSan', '13888888888')
register('001', 'zhangSan', '13888888888', year='1999')
register('001', 'zhangSan', '13888888888', year='1999', month='03')


def register2(id, name, phone, **kw):
    # 通过if选择结构 判断 year、month是否传入
    if 'year' not in kw.keys():
        print("未传入year参数")
        return
    elif 'month' not in kw.keys():
        print("未传入month参数")
        return
    dict1 = {
        'id': id,
        'name': name,
        'phone': phone,
        'other': kw
    }
    print(dict1)


register2('001', 'zhangSan', '13888888888')
register2('001', 'zhangSan', '13888888888', year='1999')
register2('001', 'zhangSan', '13888888888', year='1999', month='03')


# 命名关键字参数
# , *如果直接省略，则year、month会被当成位置参数
# 如果函数中有可变参数 则 , * 可以省略
def register3(id, name, phone, *, year, month):
    dict1 = {
        'id': id,
        'name': name,
        'phone': phone,
        'other': {
            'year': year,
            'month': month
        }
    }
    print(dict1)


def register4(id, name, phone, *args, year, month):
    print(args)
    dict1 = {
        'id': id,
        'name': name,
        'phone': phone,
        'other': {
            'year': year,
            'month': month
        }
    }
    print(dict1)


# register3('001', 'zhangSan', '13888888888')
# register3('001', 'zhangSan', '13888888888', year='1999')
# register3('001', 'zhangSan', '13888888888', '1999', '03')
register3('001', 'zhangSan', '13888888888', year='1999', month='03')

register4('001', 'zhangSan', '13888888888', year='1999', month='03')
register4('001', 'zhangSan', '13888888888', 1, 2, 3, year='1999', month='03')
register4('001', 'zhangSan', '13888888888', 1, 2, 3, 4, 5, year='1999', month='03')
